iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
佛心分享-IT 人自學之術

後端小白自學 Laravel系列 第 15

第 15 天:中間件

  • 分享至 

  • xImage
  •  

文件:中间件
中間件概念: 中間件在請求和回應的生命週期中執行操作,用於處理請求或修改回應。(可以回頭複習第 2 天:Laravel 啟服務與請求的生命週期)
建立中間件: 使用 Artisan 指令建立中間件並定義處理邏輯。
註冊中間件:Kernel 檔案中註冊中間件以便在路由中使用。
使用中間件: 可以在路由或控制器中套用中間件來執行請求過濾。

中間件是 Laravel 中用於處理 HTTP 請求的機制,當請求到達應用程式之前或在回應傳送到使用者之前執行一些操作,通常用於認證、授權、日誌記錄、請求修改等。
流程

中間件的概念


中間件可以理解為一個處理 HTTP 請求的過濾器。
當一個請求進入應用程序時,Laravel 的 HTTP 核心會依序將該請求通過路由、控制器(如果有的話)、以及註冊的 middleware。
每個中間件通常包含一個 handle 方法,該方法接收請求並可選擇處理或轉送請求。

創建和註冊自定義中間件


創建中間件
指令 php artisan make:middleware CheckAge,然後在 app/Http/Middleware/CheckAge.php 定義中間件的邏輯。

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CheckAge
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handle(Request $request, Closure $next)
    {
        // 檢查用戶是否年滿 18 歲
        if ($request->age < 18) {
            return response('You are not old enough.', 403);
        }

        return $next($request);
    }
}

$next($request) 的作用
在 middleware 中,$next($request) 的作用是將控制權交給下一個 middleware 或路由處理器(controller)。

也就是當調用 $next($request) 時,控制流程將會繼續向下,直到達到最後一個 middleware 或是路由的處理器。

註冊自定義中間件
中間件需要在 app/Http/Kernel.php 檔案中註冊,以便可以在路由中使用它。

protected $routeMiddleware = [
    // 其他中間件
    'checkage' => \App\Http\Middleware\CheckAge::class,
];

使用中間件進行請求過濾


  1. 在路由中使用
    // routes/web.php
    
    Route::get('/profile', function () {
        // 僅當 age 大於等於 18 時才能存取此路由
    })->middleware('checkage');
    
  2. 在控制器中使用
    // app/Http/Controllers/ProfileController.php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class ProfileController extends Controller
    {
        public function __construct()
        {
            $this->middleware('checkage');
        }
    
        public function show()
        {
            // 僅當 age 大於等於 18 時才能存取此方法
        }
    }
    

✍🏻每日任務


使用者訪問特定路由,要先確認是否已經登入,有登入的話轉跳歡迎頁面,沒有登入的話就轉跳到登入頁請他重新登入,所以現在需要建立一個中間件來檢查使用者是否已登入。

step 1 - 建立新的中間件
指令 php artisan make:middleware CheckAuthenticated

step 2 - 在中間件上寫邏輯判斷
指令新建的中間件檔案 app/Http/Middleware/CheckAuthenticated.php 新增檢查使用者是否已登入的邏輯。

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CheckAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handle(Request $request, Closure $next)
    {
        // 檢查用戶是否登入
        if (!auth()->check()) {
            // 如果使用者未登錄,重定向到登錄頁面
            return redirect()->route('login');
        }

        // 繼續處理請求
        return $next($request);
    }
}

step 3 - 註冊中間件
app/Http/Kernel.php 檔案中註冊中間件。
把建立的中間件加到 $routeMiddleware 陣列中,就可以在路由中使用它。

protected $routeMiddleware = [
    // 其他中間件
    'authcheck' => \App\Http\Middleware\CheckAuthenticated::class,
];

step 4 - 使用中間件
有兩種方法可以使用中間件,一種是直接掛在路由上;另一種寫在控制器,當路由引用靜態呼叫控制器方法的時候,中間件也會被使用到。

  1. 路由中使用:
    routes/web.php 檔案中,使用剛建立的中間件來保護某些路由
    use Illuminate\Support\Facades\Route;
    
    Route::get('/dashboard', function () {
        return 'This is the dashboard page!';
    })->middleware('authcheck'); // 使用中間件保護此路由
    
    Route::get('/login', function () {
        return 'This is the login page!';
    })->name('login'); // 設定登入路由的名稱
    
  2. 控制器中使用:
    // app/Http/Controllers/DashboardController.php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class DashboardController extends Controller
    {
        public function __construct()
        {
            // 將中間件應用於所有方法
            $this->middleware('authcheck');
        }
    
        public function index()
        {
            return 'Welcome to the dashboard!';
        }
    }
    
    // routes/web.php
    
    use App\Http\Controllers\DashboardController;
    
    Route::get('/dashboard', [DashboardController::class, 'index']);
    

step 5 - 測試
test_case1 存取受保護的路由:嘗試存取 /dashboard 頁面,未登入的使用者應被重新導向至 /login 頁面。
test_case2 登入使用者測試:登入後造訪 /dashboard,應能看到「Welcome to the dashboard!」訊息。


上一篇
第 14 天:RESTful API 基礎
下一篇
第 16 天:任務調度與隊列
系列文
後端小白自學 Laravel30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言